package cn.yiufung.qxquartz.service.impl;

import cn.yiufung.qxquartz.common.ScheduleConstants;
import cn.yiufung.qxquartz.entity.SystemScheduledDO;
import cn.yiufung.qxquartz.exception.TaskException;
import cn.yiufung.qxquartz.mapper.SystemScheduledMapper;
import cn.yiufung.qxquartz.service.SystemScheduledService;
import cn.yiufung.qxquartz.utils.ScheduleUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.PostConstruct;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * 定时任务业务层
 * @author 姚锋
 * @createTime 2023年08月18日 10:58:00
 */
@Service
public class SystemScheduledServiceImpl extends ServiceImpl<SystemScheduledMapper, SystemScheduledDO>
        implements SystemScheduledService {

    @Autowired
    private Scheduler scheduler;

    /**
     * 初始化定时任务
     */
    @PostConstruct
    public void initializationScheduled() {
        List<SystemScheduledDO> scheduledList = this.list();
        scheduledList.forEach(e -> {
            try {
                ScheduleUtils.createScheduleJob(scheduler, e);
            } catch (SchedulerException | TaskException ex) {
                log.error("定时任务异常" + e.getJobName(), ex);
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pauseJob(Long id) throws SchedulerException, TaskException {
        SystemScheduledDO systemScheduledDO = getById(id);
        if(ObjectUtils.isEmpty(systemScheduledDO)){
            throw new IllegalArgumentException("ID查询不到数据");
        }
        systemScheduledDO.setStatus(ScheduleConstants.Status.PAUSE.getValue());
        if(saveOrUpdate(systemScheduledDO)){
            JobKey jobKey = ScheduleUtils.getJobKey(systemScheduledDO.getId(), systemScheduledDO.getJobGroup());
            scheduler.pauseJob(jobKey);
        }else{
            throw new TaskException("更新数据异常", TaskException.Code.UNKNOWN);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resumeJob(Long id) throws SchedulerException, TaskException {
        SystemScheduledDO systemScheduledDO = getById(id);
        if(ObjectUtils.isEmpty(systemScheduledDO)){
            throw new IllegalArgumentException("ID查询不到数据");
        }
        systemScheduledDO.setStatus(ScheduleConstants.Status.NORMAL.getValue());
        if(saveOrUpdate(systemScheduledDO)){
            JobKey jobKey = ScheduleUtils.getJobKey(systemScheduledDO.getId(), systemScheduledDO.getJobGroup());
            scheduler.resumeJob(jobKey);
        }else{
            throw new TaskException("更新数据异常", TaskException.Code.UNKNOWN);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteJob(Long id) throws SchedulerException, TaskException {
        SystemScheduledDO systemScheduledDO = getById(id);
        if(ObjectUtils.isEmpty(systemScheduledDO)){
            throw new IllegalArgumentException("ID查询不到数据");
        }
        if(removeById(id)){
            JobKey jobKey = ScheduleUtils.getJobKey(systemScheduledDO.getId(), systemScheduledDO.getJobGroup());
            scheduler.deleteJob(jobKey);
        }else{
            throw new TaskException("更新数据异常", TaskException.Code.UNKNOWN);
        }
    }

    @Override
    public void run(Long id) throws SchedulerException {
        SystemScheduledDO systemScheduledDO = getById(id);
        if(ObjectUtils.isEmpty(systemScheduledDO)){
            throw new IllegalArgumentException("ID查询不到数据");
        }
        scheduler.triggerJob(ScheduleUtils.getJobKey(systemScheduledDO.getId(), systemScheduledDO.getJobGroup()));
    }

    @Override
    public void addScheduled(SystemScheduledDO systemScheduledDO) throws SchedulerException, TaskException {
        systemScheduledDO.setStatus(ScheduleConstants.Status.PAUSE.getValue());
        boolean isSave = save(systemScheduledDO);
        if(isSave){
            ScheduleUtils.createScheduleJob(scheduler, systemScheduledDO);
        }
    }

    @Override
    public void updateScheduled(SystemScheduledDO systemScheduledDO) throws SchedulerException, TaskException {
        SystemScheduledDO oldScheduledDO = getById(systemScheduledDO.getId());
        if(ObjectUtils.isEmpty(systemScheduledDO)){
            throw new IllegalArgumentException("ID查询不到数据");
        }
        if(saveOrUpdate(systemScheduledDO)){
            JobKey oldJobKey = ScheduleUtils.getJobKey(oldScheduledDO.getId(), oldScheduledDO.getJobGroup());
            if(scheduler.checkExists(oldJobKey)){
                scheduler.deleteJob(oldJobKey);
            }
            ScheduleUtils.createScheduleJob(scheduler, systemScheduledDO);
        }
    }
}
